/*
 * Copyright (C) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use crate::log_e;
use core::ops;

pub const PUBLIC_KEY_LEN: usize = 32;
pub const CHALLENGE_LEN: usize = 32;
pub const UDID_LEN: usize = 64;
pub const ROOT_SECRET_LEN: usize = 32;
pub const ED25519_FIX_SIGN_BUFFER_SIZE: usize = 64;
pub const SHA256_DIGEST_SIZE: usize = 32;
pub const AES_GCM_TAG_SIZE: usize = 16;
pub const AES_GCM_IV_SIZE: usize = 12;
pub const TOKEN_KEY_LEN: usize = 32;
pub const MAX_EVENT_NUM: usize = 20;
pub const INVALID_USER_ID: i32 = -1;
pub const ABANDON_PIN_VALID_PERIOD: u64 = 96 * 3600 * 1000;

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum ErrorCode {
    Success = 0,
    Fail = 1,
    GeneralError = 2,
    Canceled = 3,
    Timeout = 4,
    TypeNotSupport = 5,
    TrustLevelNotSupport = 6,
    Busy = 7,
    BadParam = 8,
    Locked = 9,
    NotEnrolled = 10,
    HardwareNotSupported = 11,
    PinExpired = 13,
    AuthTokenCheckFailed = 15,
    AuthTokenExpired = 16,
    ReuseAuthResultFailed = 17,
    SystemErrorCodeBeging = 1000,
    IpcError = 1001,
    InvalidContextId = 1002,
    ReadParcelError = 1003,
    WriteParcelError = 1004,
    CheckPermissionFailed = 1005,
    InvalidHdiInterface = 1006,
    BadCopy = 10003,
    NoMemory = 10004,
    NeedInit = 10005,
    NotFound = 10006,
    ReachLimit = 10007,
    DuplicateCheckFailed = 10008,
    BadRead = 10009,
    BadWrite = 10010,
    BadDelete = 10011,
    Unknown = 10012,
    BadMatch = 10013,
    BadSign = 10014,
    TokenTimeout = 10016,
    VerifyTokenFail = 10017,
    ExceedLimit = 10018,
}

impl Default for ErrorCode {
    fn default() -> Self {
        ErrorCode::GeneralError
    }
}

impl TryFrom<i32> for ErrorCode {
    type Error = ErrorCode;
    fn try_from(value: i32) -> Result<Self, ErrorCode> {
        match value {
            0 => Ok(ErrorCode::Success),
            1 => Ok(ErrorCode::Fail),
            2 => Ok(ErrorCode::GeneralError),
            3 => Ok(ErrorCode::Canceled),
            4 => Ok(ErrorCode::Timeout),
            5 => Ok(ErrorCode::TypeNotSupport),
            6 => Ok(ErrorCode::TrustLevelNotSupport),
            7 => Ok(ErrorCode::Busy),
            8 => Ok(ErrorCode::BadParam),
            9 => Ok(ErrorCode::Locked),
            10 => Ok(ErrorCode::NotEnrolled),
            11 => Ok(ErrorCode::HardwareNotSupported),
            13 => Ok(ErrorCode::PinExpired),
            15 => Ok(ErrorCode::AuthTokenCheckFailed),
            16 => Ok(ErrorCode::AuthTokenExpired),
            17 => Ok(ErrorCode::ReuseAuthResultFailed),
            1000 => Ok(ErrorCode::SystemErrorCodeBeging),
            1001 => Ok(ErrorCode::IpcError),
            1002 => Ok(ErrorCode::InvalidContextId),
            1003 => Ok(ErrorCode::ReadParcelError),
            1004 => Ok(ErrorCode::WriteParcelError),
            1005 => Ok(ErrorCode::CheckPermissionFailed),
            1006 => Ok(ErrorCode::InvalidHdiInterface),
            10003 => Ok(ErrorCode::BadCopy),
            10004 => Ok(ErrorCode::NoMemory),
            10005 => Ok(ErrorCode::NeedInit),
            10006 => Ok(ErrorCode::NotFound),
            10007 => Ok(ErrorCode::ReachLimit),
            10008 => Ok(ErrorCode::DuplicateCheckFailed),
            10009 => Ok(ErrorCode::BadRead),
            10010 => Ok(ErrorCode::BadWrite),
            10011 => Ok(ErrorCode::BadDelete),
            10012 => Ok(ErrorCode::Unknown),
            10013 => Ok(ErrorCode::BadMatch),
            10014 => Ok(ErrorCode::BadSign),
            10016 => Ok(ErrorCode::TokenTimeout),
            10017 => Ok(ErrorCode::VerifyTokenFail),
            10018 => Ok(ErrorCode::ExceedLimit),
            _ => {
                log_e!("Invalid error code: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Clone, Copy, PartialEq, Eq, Debug, PartialOrd, Ord)]
#[repr(i32)]
pub enum AuthType {
    Default = 0,
    Pin = 1,
    Face = 2,
    Fingerprint = 4,
    RecoveryKey = 8,
    PrivatePin = 16,
}

impl Default for AuthType {
    fn default() -> Self {
        AuthType::Default
    }
}

impl TryFrom<i32> for AuthType {
    type Error = ErrorCode;
    fn try_from(value: i32) -> core::result::Result<Self, ErrorCode> {
        match value {
            0 => Ok(AuthType::Default),
            1 => Ok(AuthType::Pin),
            2 => Ok(AuthType::Face),
            4 => Ok(AuthType::Fingerprint),
            8 => Ok(AuthType::RecoveryKey),
            _ => {
                log_e!("Invalid auth type: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Clone, Copy, PartialEq, Eq, Debug, PartialOrd, Ord)]
#[repr(u32)]
pub enum CredStorageType {
    StorageTypeTee = 0,
    StorageTypeMspc = 1,
}

impl TryFrom<u32> for CredStorageType {
    type Error = ErrorCode;
    fn try_from(value: u32) -> core::result::Result<Self, ErrorCode> {
        match value {
            0 => Ok(CredStorageType::StorageTypeMspc),
            1 => Ok(CredStorageType::StorageTypeMspc),
            _ => {
                log_e!("Invalid auth type: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum ScheduleMode {
    Enroll = 0,
    Auth = 1,
    Identify = 2,
    ReuseUnlockAuthResult = 3,
    Abandon = 4,
}

impl Default for ScheduleMode {
    fn default() -> Self {
        ScheduleMode::Enroll
    }
}

impl TryFrom<i32> for ScheduleMode {
    type Error = ErrorCode;
    fn try_from(value: i32) -> core::result::Result<Self, ErrorCode> {
        match value {
            0 => Ok(ScheduleMode::Enroll),
            1 => Ok(ScheduleMode::Auth),
            2 => Ok(ScheduleMode::Identify),
            3 => Ok(ScheduleMode::ReuseUnlockAuthResult),
            4 => Ok(ScheduleMode::Abandon),
            _ => {
                log_e!("Invalid schedule mode: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum UserType {
    Main = 0,
    Sub = 1,
    Private = 2,
}

impl Default for UserType {
    fn default() -> Self {
        UserType::Main
    }
}

impl TryFrom<i32> for UserType {
    type Error = ErrorCode;
    fn try_from(value: i32) -> core::result::Result<Self, ErrorCode> {
        match value {
            0 => Ok(UserType::Main),
            1 => Ok(UserType::Sub),
            2 => Ok(UserType::Private),
            _ => {
                log_e!("Invalid user type: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum AuthPropertyMode {
    InitAlgorithm = 1,
    Delete = 2,
    Get = 3,
    Set = 4,
    Freeze = 5,
    Unfreeze = 6,
    SetCachedTemplates = 7,
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum AuthSecurityLevel {
    Asl0 = 0,
    Asl1 = 1,
    Asl2 = 2,
    Asl3 = 3,
    MaxAsl = 4,
}

impl Default for AuthSecurityLevel {
    fn default() -> Self {
        AuthSecurityLevel::Asl0
    }
}

impl TryFrom<i32> for AuthSecurityLevel {
    type Error = ErrorCode;
    fn try_from(value: i32) -> core::result::Result<Self, ErrorCode> {
        match value {
            0 => Ok(AuthSecurityLevel::Asl0),
            1 => Ok(AuthSecurityLevel::Asl1),
            2 => Ok(AuthSecurityLevel::Asl2),
            3 => Ok(AuthSecurityLevel::Asl3),
            4 => Ok(AuthSecurityLevel::MaxAsl),
            _ => {
                log_e!("Invalid auth security level: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum ExecutorSecurityLevel {
    Esl0 = 0,
    Esl1 = 1,
    Esl2 = 2,
    Esl3 = 3,
    MaxEsl = 4,
}

impl Default for ExecutorSecurityLevel {
    fn default() -> Self {
        ExecutorSecurityLevel::Esl0
    }
}

impl TryFrom<i32> for ExecutorSecurityLevel {
    type Error = ErrorCode;
    fn try_from(value: i32) -> core::result::Result<Self, ErrorCode> {
        match value {
            0 => Ok(ExecutorSecurityLevel::Esl0),
            1 => Ok(ExecutorSecurityLevel::Esl1),
            2 => Ok(ExecutorSecurityLevel::Esl2),
            3 => Ok(ExecutorSecurityLevel::Esl3),
            4 => Ok(ExecutorSecurityLevel::MaxEsl),
            _ => {
                log_e!("Invalid executor security level: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(u32)]
pub enum AuthCapabilityLevel {
    Acl0 = 0,
    Acl1 = 1,
    Acl2 = 2,
    Acl3 = 3,
    MaxAcl = 4,
}

impl Default for AuthCapabilityLevel {
    fn default() -> Self {
        AuthCapabilityLevel::Acl0
    }
}

impl TryFrom<u32> for AuthCapabilityLevel {
    type Error = ErrorCode;
    fn try_from(value: u32) -> core::result::Result<Self, ErrorCode> {
        match value {
            0 => Ok(AuthCapabilityLevel::Acl0),
            1 => Ok(AuthCapabilityLevel::Acl1),
            2 => Ok(AuthCapabilityLevel::Acl2),
            3 => Ok(AuthCapabilityLevel::Acl3),
            _ => {
                log_e!("Invalid auth capability level: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum AuthTrustLevel {
    Atl0 = 0,
    Atl1 = 10000,
    Atl2 = 20000,
    Atl3 = 30000,
    Atl4 = 40000,
    MaxAtl = 5,
}

impl Default for AuthTrustLevel {
    fn default() -> Self {
        AuthTrustLevel::Atl0
    }
}

impl TryFrom<i32> for AuthTrustLevel {
    type Error = ErrorCode;

    fn try_from(value: i32) -> core::result::Result<Self, ErrorCode> {
        match value {
            0 => Ok(AuthTrustLevel::Atl0),
            10000 => Ok(AuthTrustLevel::Atl1),
            20000 => Ok(AuthTrustLevel::Atl2),
            30000 => Ok(AuthTrustLevel::Atl3),
            40000 => Ok(AuthTrustLevel::Atl4),
            _ => {
                log_e!("Invalid auth trust level: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum TokenType {
    LocalAuth = 0,
    LocalResign = 1,
    Coauth = 2,
}

impl Default for TokenType {
    fn default() -> Self {
        TokenType::LocalAuth
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum AuthIntent {
    Default = 0,
    Unlock = 1,
    SilentAuth = 2,
    AbandonedPinAuth = 4,
}

impl Default for AuthIntent {
    fn default() -> Self {
        AuthIntent::Default
    }
}

impl TryFrom<i32> for AuthIntent {
    type Error = ErrorCode;
    fn try_from(value: i32) -> core::result::Result<Self, ErrorCode> {
        match value {
            0 => Ok(AuthIntent::Default),
            1 => Ok(AuthIntent::Unlock),
            2 => Ok(AuthIntent::SilentAuth),
            4 => Ok(AuthIntent::AbandonedPinAuth),
            _ => {
                log_e!("Invalid auth intent: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum ScheduleType {
    Enroll = 1,
    Update = 2,
    Abandon = 3,
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum PinChangeScene {
    Update = 0,
    Reset = 1,
}

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[repr(i32)]
pub enum ExecutorRole {
    Collector = 1,
    Verifier = 2,
    AllInOne = 3,
}

impl Default for ExecutorRole {
    fn default() -> Self {
        ExecutorRole::Collector
    }
}

impl TryFrom<i32> for ExecutorRole {
    type Error = ErrorCode;
    fn try_from(value: i32) -> core::result::Result<Self, ErrorCode> {
        match value {
            1 => Ok(ExecutorRole::Collector),
            2 => Ok(ExecutorRole::Verifier),
            3 => Ok(ExecutorRole::AllInOne),
            _ => {
                log_e!("Invalid executor role: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum ReuseMode {
    AuthTypeRelevant = 1,
    AuthTypeIrrelevant = 2,
    CallerIrrelevantAuthTypeRelevant = 3,
    CallerIrrelevantAuthTypeIrrelevant = 4,
}

impl Default for ReuseMode {
    fn default() -> Self {
        ReuseMode::AuthTypeRelevant
    }
}

impl TryFrom<i32> for ReuseMode {
    type Error = ErrorCode;
    fn try_from(value: i32) -> core::result::Result<Self, ErrorCode> {
        match value {
            1 => Ok(ReuseMode::AuthTypeRelevant),
            2 => Ok(ReuseMode::AuthTypeIrrelevant),
            3 => Ok(ReuseMode::CallerIrrelevantAuthTypeRelevant),
            4 => Ok(ReuseMode::CallerIrrelevantAuthTypeIrrelevant),
            _ => {
                log_e!("Invalid reuse mode: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ConfigType {
    Invalid = 0,
    PinExpiredPeriod = 1,
    AuthTypeEnableStatus = 2,
}

impl Default for ConfigType {
    fn default() -> Self {
        ConfigType::Invalid
    }
}

impl TryFrom<i32> for ConfigType {
    type Error = ErrorCode;
    fn try_from(value: i32) -> core::result::Result<Self, ErrorCode> {
        match value {
            1 => Ok(ConfigType::PinExpiredPeriod),
            2 => Ok(ConfigType::AuthTypeEnableStatus),
            _ => {
                log_e!("Invalid config type: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum UserState {
    UserStateInit = 0,
    UserStatePinSuccess = 1,
    UserStatePinSuccessAndFileExist = 2,
}

impl Default for UserState {
    fn default() -> Self {
        UserState::UserStateInit
    }
}

impl TryFrom<i32> for UserState {
    type Error = ErrorCode;
    fn try_from(value: i32) -> core::result::Result<Self, ErrorCode> {
        match value {
            0 => Ok(UserState::UserStateInit),
            1 => Ok(UserState::UserStatePinSuccess),
            2 => Ok(UserState::UserStatePinSuccessAndFileExist),
            _ => {
                log_e!("Invalid user state: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(i32)]
pub enum CredentialType {
    Default = 0,
    Secondary = 1,
    CloudRecoveryKey = 100,
    EnterpriseRecoverykey = 101,
    PinSix = 10000,
    PinNumber = 10001,
    PinMixed = 10002,
    PinFour = 10003,
    PinPattern = 10004,
    PinQuestion = 10005,
}

impl Default for CredentialType {
    fn default() -> Self {
        CredentialType::Default
    }
}

impl TryFrom<i32> for CredentialType {
    type Error = ErrorCode;
    fn try_from(value: i32) -> core::result::Result<Self, ErrorCode> {
        match value {
            0 => Ok(CredentialType::Default),
            1 => Ok(CredentialType::Secondary),
            100 => Ok(CredentialType::CloudRecoveryKey),
            101 => Ok(CredentialType::EnterpriseRecoverykey),
            10000 => Ok(CredentialType::PinSix),
            10001 => Ok(CredentialType::PinNumber),
            10002 => Ok(CredentialType::PinMixed),
            10003 => Ok(CredentialType::PinFour),
            10004 => Ok(CredentialType::PinPattern),
            10005 => Ok(CredentialType::PinQuestion),
            _ => {
                log_e!("Invalid credential type: {}", value);
                Err(ErrorCode::BadParam)
            }
        }
    }
}
